#include "ESP01s_Control.h"

TaskHandle_t xSensorDataHandle = NULL;

uint8_t ESP_index = 0;
esp_state_t ESP_state = ESP_STATE_IDLE;

void ESP_AutoConnect(void) {
    ESP_index = 0;
    ESP_state = ESP_STATE_IDLE;
    OLED_ShowString(1, 1, "ESP AUTO START");
	
    USART_SendString(&USART2_Cfg, (const unsigned char*)at_espcmds[0].cmd, strlen(at_espcmds[0].cmd));  // 发送第一条AT指令
}

/**
 * @brief  检查esp-01s的状态，并且实现重新联网
 * @param  msg.data
 * @retval 无
 * @note   
 */
// ESP_control.c
void ESP_StateTransition(char *resp) {
    static uint8_t retry_count = 0;
    const uint8_t max_retry = 5;
	
//	USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line25 | resp: %s \r\n", resp);
	
    if(strncmp(resp, "OK", 2) == 0) {    /* 成功响应处理 */
//		USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line28\r\n");
		SYS_BLLED_shortBlink();
        retry_count = 0; 		// 重置重试计数器
		
        if( at_espcmds[ESP_index].state == ESP_STATE_IDLE ||	// 自动发送下一条开机指令
			at_espcmds[ESP_index].state == ESP_STATE_WIFI_CONNECT ||
		    at_espcmds[ESP_index].state == ESP_STATE_TCP_CONNECT ||
		    at_espcmds[ESP_index].state == ESP_STATE_TX_PREPARE ||
			at_espcmds[ESP_index].state == ESP_STATE_TRANSPARENT
		){
        
//			USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line37\r\n");
			
			OLED_Clear(); 
			ESP_state = at_espcmds[ESP_index].state;
			OLED_ShowString(1, 1, "ESP STATE");
			OLED_ShowString(2, 1, (const char*)ESP_state);

			ESP_index++;
            USART_SendString(&USART2_Cfg, (const unsigned char*)at_espcmds[ESP_index].cmd, strlen(at_espcmds[ESP_index].cmd));
        } else if(at_espcmds[ESP_index].state == ESP_STATE_HTTP_CONNECT){
			//USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line44\r\n");
			
			ESP_index = 5;
			ESP_state = ESP_STATE_HTTP_CONNECT;
			
			OLED_Clear(); 
            OLED_ShowString(1, 1, "AUTO READY!");
			if(xSensorDataHandle == NULL) {
				xTaskCreate(vTask_ESP01s_SensorData_Push, "vTask_ESP01s_SensorData_Push", 128, NULL, 1, &xSensorDataHandle);
			}
        }
    }
    else if((strncmp(resp, "FAIL", 4) == 0|| strncmp(resp, "ERROR", 5) == 0)) {  /* 失败响应处理 */
		SYS_RLED_shortBlink();
//		USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line58\r\n");
		
        if(++retry_count < max_retry) {	            			// 延时后重发当前指令
			
			//USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line62\r\n");

            vTaskDelay(pdMS_TO_TICKS(1000)); 
            USART_SendString(&USART2_Cfg, (const unsigned char*)at_espcmds[ESP_index].cmd, strlen(at_espcmds[ESP_index].cmd));
            OLED_ShowString(3, 1, "Retrying...");
        } else {       											// 彻底失败时重置
            //USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line68\r\n");
			
			retry_count = 0;
            ESP_index = 0;
            ESP_state = ESP_STATE_IDLE;
			
            OLED_ShowString(3, 1, "RESETTING...");
            vTaskDelay(pdMS_TO_TICKS(1000));
            ESP_AutoConnect();
        }
    }
	else if(strncmp(resp, "HTTP/1.1 200 OK", 15) == 0 || strncmp(resp, "HHTTP/1.1 200 OK", 16) == 0){
		ESP_index = 5;
		ESP_state = ESP_STATE_HTTP_CONNECT;
		
		if(xSensorDataHandle == NULL) {
			OLED_Clear(); 
			OLED_ShowString(1, 1, "AUTO READY!");
			xTaskCreate(vTask_ESP01s_SensorData_Push, "vTask_ESP01s_SensorData_Push", 128, NULL, 1, &xSensorDataHandle);
		}
	}
	
	memset(resp, strlen(resp), 0);
}

void vTask_ESP01s_SensorData_Push(void *arg){
//	USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line91 | esp_state: %d\r\n", ESP_index);
    while(ESP_state == ESP_STATE_HTTP_CONNECT) { // 增加状态判断
		taskENTER_CRITICAL();
		
        ESP_SendPacket();
		
		taskEXIT_CRITICAL();
		
		SYS_BLLED_shortBlink();
        vTaskDelay(pdMS_TO_TICKS(20000)); // 建议用宏保证可读性
    }
    vTaskDelete(NULL); // 自动删除任务
//	USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line97 | esp_state: %s\r\n", ESP_index);
}

void ESP_SendPacket(void) {
    char payload[MAX_MSG_LEN];
	
	// 1. 采集数据
	uint16_t adc_val = AD_GetValue(ADC_Channel_1);
    int payload_len = snprintf(payload, sizeof(payload), "GET /0 HTTP/1.1\r\nuser-agent: STM32\r\n\r\n[PESS CH1:%d]", adc_val);
	
	// 2. 发送数据至服务器
	payload[payload_len] = '\0';
    USART_SendString(&USART2_Cfg, (const unsigned char*)payload, strlen(payload));  	
	
	// 3. 发送数据至OLED
	OLED_Clear();
	OLED_ShowString(1, 1, "PESS CH1:");		
	OLED_ShowUnsignedNum(2, 1, adc_val, 4);	

	// 4. 根据传感器反馈值控制小灯
	if(adc_val >= 2000){
		GPIO_WriteBit(SNR_LED_PORT, SNR_LED_PIN, (BitAction)LED_OFF);
	}else{
		GPIO_WriteBit(SNR_LED_PORT, SNR_LED_PIN, (BitAction)LED_ON);
	}	
}
